/*
 *  Copyright (C) 1993  Robert Davis
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of Version 2, or any later version, of 
 *  the GNU General Public License as published by the Free Software 
 *  Foundation.
 */


static char RCSId[]="$Id: ContourUserPane.m,v 1.2 1993/05/04 16:21:30 davis Exp $";

#import <appkit/Application.h>
#import <appkit/publicWraps.h>		/* NXBeep() */
#import <appkit/TextField.h>

#import "CellScrollView.h"
#import "ContourUserPane.h"
#import "DoubleObject.h"
#import "DoubleValueSortedList.h"
#import "EditMatrix.h"
#import "Status.h"
#import "StatusContour.h"
#import "SubCell.h"


@interface ContourUserPane (Private)
- _updateControlsForSelectedLevel;
@end



@implementation ContourUserPane

- init
{
    [super init];

    [NXApp loadNibSection: "ContourUserPane.nib"
		    owner: self
		withNames: NO
		 fromZone: [self zone]];

    /*  Setup the scroll view  */

    [scrollView initMatrixCellClass:[SubCell class] cols:1];
    levelsMatrix = [scrollView cellMatrix];
    [[levelsMatrix setAction:@selector(selectLevel:)] setTarget:self];

    return self;
}


- (BOOL)updateStatus:aStatus doc:aDoc
{
    BOOL	isEnabled;

    if ([super updateStatus:aStatus doc:aDoc]) {

	levelsList = [status levelDefs];
	[scrollView loadCol:0 from:levelsList];

    } else
	[scrollView loadCol:0 from:nil];

    [self selectLevel:self];
    [addButton setEnabled:isEnabled = [doc isEnabled]];
    [valueField setEnabled:isEnabled];
    [valueFieldTitle setEnabled:isEnabled];
    [levelsMatrix setEnabled:isEnabled];
    [deleteButton setEnabled:isEnabled = (isEnabled
					  && [levelsMatrix selectedCell])];
    [modifyButton setEnabled:isEnabled];

    return YES;
}


- add:sender
{
    DoubleObject	*doubleObject;
    int		location;
    BOOL	changed = YES;

    doubleObject = [[DoubleObject allocFromZone:[status zone]]
				 initFromDouble:[valueField doubleValue]];
    location = [levelsList addObjectIfDoubleAbsent:doubleObject];

    if (location == NX_NOT_IN_LIST) {
	[doubleObject free];
	location = [levelsMatrix selectedRow];
	changed = NO;
	NXBeep();
    }

    [scrollView loadCol:0 from:levelsList];
    [levelsMatrix scrollCellToVisible:location :0];
    [levelsMatrix selectCellAt:location :0];

    [self selectLevel:self];
    if (changed)
	[status reportSettingsChange:self];

    return self;
}


- modify:sender
{
    DoubleObject	*dobj = [[levelsMatrix selectedCell] subObject];
    int			location;

    [dobj setDoubleValue:[valueField doubleValue]];

    /*  
     *  Remove the level from the list and reinsert it,
     *  to maintain the sort order of the list.
     */
    location = [levelsList addObject:[levelsList removeObject:dobj]];
    [scrollView loadCol:0 from:levelsList];
    [levelsMatrix scrollCellToVisible:location: 0];
    [levelsMatrix selectCellAt:location :0];
    [self selectLevel:self];

    [status reportSettingsChange:self];
    return self;
}



- delete:sender
{
    int		i;
    int		maxrow = [levelsMatrix cellCount] - 1;
    int		row = maxrow;
    BOOL	gotRow = NO;

    for (i = maxrow; i >= 0; i--) {
	SubCell	*cell = [levelsMatrix cellAt:i:0];

	if ([cell isHighlighted]) {
	    /*
	     *  If a cell is highlighted, remove (and free) the
	     *  corresponding item from the list of DoubleObjects.
	     */
	    [[levelsList removeObject:[cell subObject]] free];

	    if (!gotRow) {
		row = (i == maxrow)? i - 1 :i;
		gotRow = YES;
	    } else
		row--;
	}
    }

    [scrollView loadCol:0 from:levelsList];

    [levelsMatrix selectCellAt:row :0];
    [levelsMatrix scrollCellToVisible:row :0];
    [self selectLevel:self];

    if (gotRow)		/* gotRow will be YES if any cells were deleted */
	[status reportSettingsChange:self];

    return self;
}



/*  
 *  Selects a level if none is selected and then updates the controls 
 *  based on the selected level.
 */
- selectLevel:sender
{
    if (![levelsMatrix selectedCell]
	&& ![levelsMatrix multipleCellsSelected]) {

	[levelsMatrix selectCellAt:0:0];

    }

    [self _updateControlsForSelectedLevel];
    return self;
}


// Shuts up the compiler about unused RCSId
- (const char *) rcsid
{
    return RCSId;
}


@end



@implementation ContourUserPane (Private)

- _updateControlsForSelectedLevel
{
    SubCell	*singleCell = [levelsMatrix selectedCell];
    BOOL	enabled = (singleCell || [levelsMatrix multipleCellsSelected]);

    if (singleCell) {
	DoubleObject *dobj = [singleCell subObject];

	[valueField setDoubleValue:[dobj doubleValue]];

    } else {

	[valueField setStringValue:""];
    }

    [deleteButton setEnabled:enabled];
    [modifyButton setEnabled:singleCell? YES:NO];
    [valueField selectText:self];

    return self;
}


@end
